package com.tedu.api;
/**
 * JavaSE    基础语法   JavaOOP   JavaAPI【用--新华词典】
 * 理解：查手册-类、抽象类、接口：具体的功能【构造器、方法、属性】----使用功能
 * 要求：会查API手册     JDK1.11--向下兼容JDK1.8
 * JDK1.8.CHM文件     打不开--->framework4.0
 * 左侧位---Packages      ①所有查包   【记住类在具体包】
 * String类----Java写好的类  位于java.lang包下
 * 位于java.lang包下的类，可以不用导包
 * 左侧下位：接口、类、枚举、异常、错误、注解
 * 已知现有包含：接口、类、抽象类  8000左右类【需要用、学】
 * 知道一个类--API文件查【解释跟参考】--使用类
 * 【常用API：字符串、包装类、集合【泛型】、线程、多线程、IO流、异常、Socket套接字-网络编程】
 * 高手提供     类       抽象类      接口
 * 使用并学习
 */
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import org.junit.Test;
import java.util.Locale;
import java.util.Scanner;

/**  JavaAPI帮助文档
 *   String字符串类-----位于Java.lang包下：不需要导入包
 *   String特性：String类不可改变，由final修饰，不可以被继承
 *   字符串---通过字符数组----组成【底层封装字符数组，针对字符数组操作算法】
 *   字符串一旦创建，对象永远无法改变，但是字符串可以重新赋值
 *   Java字符串在内存中采用Unicode编码集【顶级编码集】：
 *   任意一个字符对应两个字节的定长编码，存汉字还是字母2个字节
 */
public class StringAPI {
    @Test
    public void testString() {
        char[] c = {'H', 'E', 'L', 'L', 'O'}; //定义字符静态数组---字符串
        System.out.println(c);
        String str = "Hello";     //字符数组方法与属性--字符串共享
        str = "world";  //覆盖--修改
        System.out.println(str + "1");//新对象
    }

    /**
     * 常量池
     * String 存在常量池{内存---JVM---堆}------>好处:减少内存开销
     * Java 为了提高性能，静态字符串（字面量/常量/常量链接结果）
     * 在常量池中创建    并且使用同一个对象   重用静态字符串
     * 对于重复出现字符串直接量  JVM虚拟机会从常量池当中进行获取
     * 如果查找到,返回改对象！
     */
    @Test
    public void testString1() {
        String s1 = "java123";
        String s2 = "java123";
        System.out.println(s1 == s2);//true   java123从常量池获取
        String s3 = "java" + "123";
        System.out.println(s1 == s3); //true
        //+代表拼接字符串 JVM虚拟机对于字符串做优化:右侧字面量形式自动计
        // 计算和结果:通过引用进入堆内存中  找常量池中存在:java123死值
        //s3重用s1的对象
        String s = "java";
        String s4 = s + "123"; //新对象:无法从常量池获取
        //JVM虚拟机进行优化:引用对象+字面量  不可以进行计算
        System.out.println(s1 == s4);// false
        String s5 = new String("java123");//引用类型
        //new出来的对象全新的对象
        System.out.println(s1 == s5);
    }

    /**
     * String API 常用方法
     * length（）方法  返回值:int
     * 用法:返回当前字符串的长度（个数）
     * 字符串:包括空格，字符，汉字。。。
     * String 类采用Unicode编码类:一个字符  占两个字节
     */
    @Test
    public void testLength() {
        String s = "hello";//占十个字节   使用length从1开始
        System.out.println(s.length());
        String s1 = "                                                                          我爱Java";//去掉空格   空格占字节
        System.out.println(s1.length());
    }

    /**
     * String API常用方法
     * indexOf方法【重点】
     * 用法:查找指定字符串中，首次出现的位置【下标位置】
     * 如果没有查到，返回-1
     */
    @Test
    public void testIndexOf() {
        String str = "thinking in java";
        int index = str.indexOf("java");
        System.out.println("返回坐标位置:" + index);
        //重载方法:方法名相同  参数不同
        //indexOf("查找字符串"；字符串位置)
        //功能:从指定位置下进行查找，下一个in的位置
        index = str.indexOf("in", 3);
        System.out.println("返回坐标位置:" + index);
        //5 下标位置:往后一位查找   第二次出现in的位置
    }

    /**
     * String API方法
     * lastIndexOf ("字符")
     * 用法:找到字符串中包含"字符"的最后一次出现位置【下标位置】
     */
    @Test
    public void testLastIndexOf() {
        String s = "thinking in java";
        int index = s.lastIndexOf("n");
        System.out.println("最后出现位置:" + index);
    }

    /**
     * 【重点中的重点】
     * subString(int start, int end)方法
     * 用法:截取字符串  ，  从start处开始截取到end【口诀:含头不含尾】
     * www.baidu.com
     * subString(int start, int end)方法  返回值:String
     * 用法:截取字符串,从start处开始截取,没有end 直接截取到最后
     */
    @Test
    public void testSubString() {
        String url = "www.baidu.com";
        //需求:获取当前字符串中:baidu,子字符串
        String s = url.substring(5, 9);
        System.out.println("截取后的子字符串:" + s);
        //需求:获取当前url 字符串中:百度.com
        String s1 = url.substring(4);
        System.out.println("截取到最后的字符串:" + s1);
    }

    /**
     * trim()
     * 用法:去掉字符串中两边的空格
     * 验证码:XXX      解决:并发问题【延迟操作】
     * 产生异常:StringIndexOutOfBoundsException
     * 字符串下标越界异常
     * 产生原因:下标超出字符串实际下标数
     */
    @Test
    public void testTrim() {
        String str = " x34d ";//字符:12个:空格算
        str = str.trim();//覆盖:不写前面数据类型
        System.out.println(str);
    }

    /**
     * charAt(int index)
     * 用法:返回字符串中对应下标的字符
     */
    @Test
    public void testCharAt() {
        String str = "thinking in java";    //java编程思想  第四版
        char c = str.charAt(1);
        System.out.println("获取的字符是:" + c);
    }

    /**
     * 验证码: X43d        统一将验证码转换为小写或者大写
     * toUpperCase()    字符串转换为大写
     * toLowerCase()   字符串转换为小写
     */
    @Test
    public void testUL() {
        String str = " X43d";  //判断:大小写分明   需求:去空格  转大小写
        str = str.toLowerCase().trim();
        System.out.println("转小写:" + str);
        str = str.toUpperCase().trim();
        System.out.println("转大写:" + str);
    }

    /**
     * 【重点:ser
     * 静态方法:通过类名直接调用方法
     * valueOf()   返回值:boolean
     * 用法:将java中基础数据类型转换为字符串
     */
    @Test
    public void testValueOf() {
        int i = 123;
        String s = String.valueOf(i);
        //验证:当前s对象是否等于"123"    equals()默认:对比对象,死值对比死值
        if (s.equals("123")) {//字面量:equals(字面量)  按照实际值判断
            System.out.println("是字符串，转换成功~");
        } else {
            System.out.println("不是字符串,转换失败~");
        }

    }

    /**
     * 正则表达式   匹配【验证】字符串    不作为重点【了解    PHP】
     * 过来字符串中数值正则写法:^[0-9]*$    -----JavaScript【重点】
     * matches()方法
     * 作用:用于字符串验证   通过正则表达式进行验证【过滤字符】
     */

    public static void main(String[] args) {
        String regex = "^[0-9]*$";   //验证数值
        System.out.println("请输入:");
        Scanner input = new Scanner(System.in);//从控制台输入:用来测试
        //验证 从控制台输入数值，matches方法验证是否是数值
        if (input.nextLine().matches(regex)) {
            System.out.println("是数字");
        } else {
            System.out.println("不是数字");
        }

    }


    /**
     * replace(String a,String b)方法   返回值String【子字符串】   不支持正则
     * 第一个参数:String a 要被替换的子串
     * 第二个参数:String b 用于替换的新字符串
     * 作用:用于替换字符串中特定子串
     */
    @Test
    public void testReplace() {
        String url = "www.baidu.com";
        url = url.replace("baidu", "wang");//覆盖
        System.out.println("替换子字符串:" + url);
    }

    /**
     * replaceAll()替换字符串
     * 作用:替换所有字符串的内容,支持正则
     */
    @Test
    public void testAll() {
        String regex = "^[\\u4e00-\\u9fa5]{0,}$";
        String str = "字符串";
        //  str.replaceAll(regex,"***");//支持正则
        // str.replace(regex,"***");//不支持正则
        System.out.println("支持正则:" + str);
    }

    /**
     * split(分割)    返回值:String[]   返回数组--遍历
     * 作用:按照正则或者字符串方式分割字符串
     * .正则有特殊的表达含义,匹配一个字符
     * 用\\.代表.
     * <p>
     * 需求 :ww.baidu.com按照点的方式分割url地址
     */
    @Test
    public void testSplit() {
        String url = "www.baidu.com";
        String[] str = url.split("\\.");
        //增强for 遍历 str   字符串数组
        for (String s : str) { //接受类型:字符串数组引用
            System.out.println("切割后的子字符串" + s);
        }
        System.out.println(str[1]);
    }
    //查API----split方法---数组下标越界
    //String字符串  重点  替换   截取【需要知道下标】  分割【获取部分子字符串】
    // StringBuilder与 StringBuffer【方法完全一致  功能  追加   插入   替换
    //解决:String类拼接【不要用＋】内存溢出---硬盘---程序会卡
    //"123"+"456"+"789"  牵扯拼接   建议SB
/**
 * 笔试题
 *  StringBuilder与 StringBuffer的区别
 *
 *   StringBuilder----JDK1.5----不考虑线程安全【效率高
 *    StringBuffer---JDK1.0---考虑线程安全【效率低
 */
}





















































